package com.e3.template.tgf;

import java.util.ArrayList;
import java.util.List;

import com.e3.web.core.model.SuperModel;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.ModelReader;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.PagingModelMemoryProxy;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel;
import com.extjs.gxt.ui.client.widget.layout.CardLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * 用两个Grid进行查询结果分页和直接给grid赋值进行分页。
 * 重载父类setGridValues方法，将结果值放在内存Proxy中实现内存中分页。
 * @author Janty
 *
 * @param <D>
 */
public abstract class TGFPagingGridPanel<D extends SuperModel> extends TGFGridPanel<D> {

	private PagingLoader<PagingLoadResult<D>> pagingLoader;
	
	private PagingToolBar toolBar1 = new PagingToolBar(50);
	private PagingToolBar toolBar2 = new PagingToolBar(50);
	
	private Grid<D> memGrid;
	private ListStore<D> memStore;
	private PagingLoader<PagingLoadResult<D>> memPagingLoader;
	private PagingModelMemoryProxy memProxy;
	private GridSelectionModel<D> memGridSelectionModel;
	
	private ContentPanel content1 = new ContentPanel();
	private ContentPanel content2 = new ContentPanel();
	private CardLayout cardLayout = new CardLayout();
	
	private Object loadCondtion;

	protected void initContent(){
		toolBar1.bind(getPagingLoader());
		toolBar2.bind(getMemPagingLoader());
		
		LayoutContainer lc = new LayoutContainer(cardLayout);
		
		content1.setLayout(new FitLayout());
		content1.setHeaderVisible(false);
//		content1.setHeading("content1");
		getGrid().setLoadMask(true);
		content1.add(getGrid());
		content1.setBottomComponent(toolBar1);
		lc.add(content1);
		
		content2.setLayout(new FitLayout());
		content2.setHeaderVisible(false);
//		content2.setHeading("content2");
		content2.add(getMemGrid());
		content2.setBottomComponent(toolBar2);
		lc.add(content2);
		
		cardLayout.setActiveItem(content1);
		
		add(lc);
	}
	
	@SuppressWarnings("rawtypes")
	@Override
	protected ListLoader getGridLoader(){
		return getPagingLoader();
	}
	
	private PagingLoader<PagingLoadResult<D>> getPagingLoader(){
		if(pagingLoader == null){
			pagingLoader = new BasePagingLoader<PagingLoadResult<D>>(getPagingLoaderProxy(),new ModelReader()){
				
				@Override
				protected void onLoadSuccess(Object loadConfig,PagingLoadResult<D> result) {
					super.onLoadSuccess(loadConfig, result);
				}

				@Override
				protected void onLoadFailure(Object loadConfig, Throwable t) {
					super.onLoadFailure(loadConfig, t);
				}
			};
		}
		return pagingLoader;
	}
	
	protected RpcProxy<PagingLoadResult<D>> getPagingLoaderProxy(){
		RpcProxy<PagingLoadResult<D>> proxy = new RpcProxy<PagingLoadResult<D>>() {
			@Override
			protected void load(Object loadConfig,AsyncCallback<PagingLoadResult<D>> callback) {
				PagingLoadConfig config = (PagingLoadConfig)loadConfig;
				config.set("LOAD_CONDTION", getLoadCondtion());
				getPagingData(config,callback);
			}
		};
		return proxy;
	}
	
	public Object getLoadCondtion() {
		return loadCondtion;
	}

	public void setLoadCondtion(Object loadCondtion) {
		this.loadCondtion = loadCondtion;
	}
	
	public void refreshPaging(Object qc){
		cardLayout.setActiveItem(content1);
		setLoadCondtion(qc);
		toolBar1.refresh();
	}

	@Override
	public void setGridValues(List<D> models) {
		cardLayout.setActiveItem(content2);
		getMemProxy().setData(models);
		toolBar2.refresh();
	}
	
	public void setGridContextMenu(Menu menu){
		super.setGridContextMenu(menu);
		getMemGrid().setContextMenu(menu);
	}
	
	@Override
	public Grid<D> getCurrentGrid(){
		return getActiveGrid();
	}
	
	private Grid<D> getActiveGrid(){
		ContentPanel c = (ContentPanel)cardLayout.getActiveItem();
		if(c == content1){
			return getGrid();
		}
		return getMemGrid();
	}
	
	private Grid<D> getMemGrid(){
		if (memGrid == null) {
			List<ColumnConfig> configs = getGridColumnConfigs();
			ColumnModel cm = new ColumnModel(configs);
			
			memGrid = new Grid<D>( getMemGridStore(), cm){
				protected void onDoubleClick(GridEvent<D> e) {
				    onGridRowDoubleClicked(e.getModel());
				}
			};	
			memGrid.setSelectionModel(getMemGridSelectionModel());
			afterCreateGrid(memGrid);
		}
		return memGrid;
	}
	
	private GridSelectionModel<D> getMemGridSelectionModel(){
		if(memGridSelectionModel==null){
			memGridSelectionModel = new GridSelectionModel<D>();
			memGridSelectionModel.addSelectionChangedListener(new SelectionChangedListener<D>(){
				@Override
				public void selectionChanged(SelectionChangedEvent<D> se) {
					D model = se.getSelectedItem();
					onGridSelectionChanged(model);
				}
			});
		}
		return memGridSelectionModel;
	}
	
	private ListStore<D> getMemGridStore(){
		if(memStore==null){
			memStore = createGridStore(getMemPagingLoader());
		}
		return memStore;
	}

	private PagingLoader<PagingLoadResult<D>> getMemPagingLoader(){
		if(memPagingLoader == null){
			memPagingLoader = new BasePagingLoader<PagingLoadResult<D>>(getMemProxy());
		}
		return memPagingLoader;
	}
	
	private PagingModelMemoryProxy getMemProxy(){
		if(memProxy == null){
			memProxy = new PagingModelMemoryProxy(new ArrayList<D>());
		}
		return memProxy;
	}
	
	protected abstract void getPagingData(PagingLoadConfig config,AsyncCallback<PagingLoadResult<D>> callback);
}
